package com.ljw.punishment.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.ljw.punishment.baserule.AndRelationGroup;
import com.ljw.punishment.baserule.CommonRule;
import com.ljw.punishment.baserule.OrRelationGroup;
import com.ljw.punishment.entry.ShopRuleGroupDAO;
import com.ljw.punishment.entry.ShopSceneInfoDAO;
import com.ljw.util.RewardCodeGenerator;
import com.ljw.util.RuleEffectType;
import com.ljw.util.RuleRelationTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.support.composite.CompositeRule;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @author lijunwei
 * @date 2025/5/21
 */
@Slf4j
public class SceneBuilderServiceImpl {

    public List<CompositeRule> builderRuleByRewardCode(String rewardCode, Map<Integer, Facts> resultMapEmptyCollection) throws Exception {
        if (StringUtils.isBlank(rewardCode)) {
             new Exception("奖惩编码 rewardCode不能为空");
        }
        //获取场景(子模块列表)  shop_scene_info
       // List<ShopSceneInfoDAO> shopSceneInfoDoList = shopSceneInfoRepository.querySceneByCode(rewardCode);
        String shopSceneInfoDoListStr = "[{\"conflictType\":\"throwException\",\"createdBy\":\"shiqi@tuhu.cn\"," +
                "\"effectiveType\":0,\"executeType\":0,\"id\":2164,\"rewardCode\":\"check20250519160417339\"," +
                "\"sceneName\":\"关键规则\",\"sceneType\":\"check\",\"subviewId\":2301,\"viewId\":811}]\n";
        List<ShopSceneInfoDAO> shopSceneInfoDoList = JSON.parseObject(shopSceneInfoDoListStr,
                new TypeReference<List<ShopSceneInfoDAO>>() {
                });
        if (CollectionUtils.isEmpty(shopSceneInfoDoList)) {
            log.warn("奖惩编码" + rewardCode + "在数据库中不存在生效的规则");
            return Collections.emptyList();
        }

        List<CompositeRule> ruleList = new ArrayList<>();
        //shop_scene_info
        for (ShopSceneInfoDAO sceneInfoDAO : shopSceneInfoDoList) {
            //是否处于生效状态
            boolean effective = isEffective(sceneInfoDAO);
            if (!effective) {
                return Collections.emptyList();
            }
            // 这里只会有一条   shop_rule_group
           // List<ShopRuleGroupDAO> shopRuleGroupDoList = shopRuleGroupRepository.queryShopRuleGroupByCode(rewardCode, sceneInfoDAO.getId());
            String shopRuleGroupDoListStr = "[{\"description\":\"场景：关键规则, rewardCode :check20250519160417339下的分组\"," +
                    "\"groupPriority\":2147483647,\"groupType\":\"and\",\"id\":2157," +
                    "\"name\":\"场景：关键规则规则组4b30f3e6780b4623a068f1505eef792f\",\"rewardCode\":\"check20250519160417339\"," +
                    "\"sceneId\":2164}]\n";
            List<ShopRuleGroupDAO> shopRuleGroupDoList = JSON.parseObject(shopRuleGroupDoListStr,
                    new TypeReference<List<ShopRuleGroupDAO>>() {
                    });
            if (CollectionUtils.isEmpty(shopRuleGroupDoList)) {
                log.warn("rewardCode :{} 不存在规则组，构建规则为空", rewardCode);
                return Collections.emptyList();
            }
            // 一个group生成一个组合Rule 目前只有And
            CompositeRule compositeRule = buildSceneTotalRule(sceneInfoDAO, shopRuleGroupDoList, resultMapEmptyCollection);
            ruleList.add(compositeRule);
        }

        log.info("=== SceneBuilder == 场景构建完成 rules :{}", JSONObject.toJSONString(ruleList));
        return ruleList;
    }


    public CompositeRule buildSceneTotalRule(ShopSceneInfoDAO sceneInfoDAO, List<ShopRuleGroupDAO> shopRuleGroupDoList, Map<Integer, Facts> resultMapEmptyCollection) throws Exception {

        String rewardCode = sceneInfoDAO.getRewardCode();

        // 基础condition，每个group都要包含的，比如：规则有效时间
        Set<CommonRule> baseRule = getCommonRules(resultMapEmptyCollection, sceneInfoDAO);

        CompositeRule totalGroup = new AndRelationGroup(sceneInfoDAO.getId(), sceneInfoDAO.getSceneName() + RewardCodeGenerator.generatorUuid(), rewardCode, baseRule);

        RuleLoaderServiceImpl ruleLoaderService = new RuleLoaderServiceImpl();
        //shop_rule_group
        for (ShopRuleGroupDAO shopRuleGroupDAO : shopRuleGroupDoList) {
            String groupType = shopRuleGroupDAO.getGroupType();
            //and  或者 or
            RuleRelationTypeEnum relationTypeEnum = RuleRelationTypeEnum.getRelationVyCode(groupType);
            if (relationTypeEnum == null) {
                 new Exception(rewardCode + "不存在的规则组类型");
            }
            // 模块下的规则  处理 每个 shop_rule_group 下对应的多个 shop_rule_info
            Set<CommonRule> ruleGroup = ruleLoaderService.createRuleByGroupId(rewardCode, shopRuleGroupDAO.getId());
            CompositeRule compositeRule = null;
            if (RuleRelationTypeEnum.AND == relationTypeEnum) {
                compositeRule = new AndRelationGroup(shopRuleGroupDAO.getId(), shopRuleGroupDAO.getName(), rewardCode, ruleGroup);
            }
            if (RuleRelationTypeEnum.OR == relationTypeEnum) {
                compositeRule = new OrRelationGroup(shopRuleGroupDAO.getId(), shopRuleGroupDAO.getName(), rewardCode, ruleGroup);
            }

            totalGroup.addRule(compositeRule);
        }
        return totalGroup;
    }

    /**
     * @param resultMapEmptyCollection 结果
     * @param shopSceneInfoDAO 场景
     * @return 构造的基础场景规则: 1.规则的生效时间
     */
    private Set<CommonRule> getCommonRules(Map<Integer, Facts> resultMapEmptyCollection, ShopSceneInfoDAO shopSceneInfoDAO) {
        Set<CommonRule> baseRuleSet = new HashSet<>();
        CommonRule commonRule = new CommonRule("场景：" + shopSceneInfoDAO.getSceneName() + RewardCodeGenerator.generatorUuid(), "场景总规则", 0, resultMapEmptyCollection);
        if (RuleEffectType.TIME_RANGE.code().equals(shopSceneInfoDAO.getEffectiveType())) {
            Map<String, Object> extendParam = new HashMap<>();
            extendParam.put("startDate", shopSceneInfoDAO.getBeginDate());
            extendParam.put("endDate", shopSceneInfoDAO.getEndDate());
            commonRule.when("dateAfter(getCurrentDate(),startDate) && dateAfter(endDate,getCurrentDate())", extendParam);
        } else {
            commonRule.when("true");
        }
        commonRule.setRewardCode(shopSceneInfoDAO.getRewardCode());
        commonRule.setId(shopSceneInfoDAO.getId());
        commonRule.then(String.valueOf(shopSceneInfoDAO.getId()));
        baseRuleSet.add(commonRule);
        return baseRuleSet;
    }

    /**
     * 判断规则是否生效，满足任意一条：
     * 1、规则长期有效；
     * 2、规则固定时间有效：当前时间在规则配置的有效期内
     *
     * @return 是否处于生效状态
     */
    private boolean isEffective(ShopSceneInfoDAO sceneInfoDAO) {
        Date now = new Date();
        if (RuleEffectType.TIME_RANGE.code().equals(sceneInfoDAO.getEffectiveType())
                && (now.before(sceneInfoDAO.getBeginDate()) || now.after(sceneInfoDAO.getEndDate()))) {
            log.info("rewardCode :{} , id :{} 已过期未加载规则", sceneInfoDAO.getRewardCode(), sceneInfoDAO.getId());
            return false;
        }
        return true;
    }

}
